package shop

import (
	"fmt"
	"math"
	"time"

	"webcppcluster/cache"
	"webcppcluster/config"
	"webcppcluster/db"
	"webcppcluster/lobby"
	"webcppcluster/utils"
)

// GetShopCfg 获取商城配置
func GetShopCfg(version int) map[string]interface{} {
	shoplist := []map[string]interface{}{}

	for _, id := range config.ShopList {
		cfg, ok := config.ShopCfg[id]
		if !ok {
			continue
		}
		if version < cfg.Version {
			continue
		}

		propdict := map[string]interface{}{
			"pid":         cfg.PID,
			"ename":       cfg.EName,
			"name":        cfg.Name,
			"type":        cfg.Type,
			"pay":         cfg.Pay,
			"money":       cfg.Money,
			"coin":        cfg.Coin,
			"rmb":         cfg.RMB,
			"paytype":     cfg.PayType,
			"iconid":      cfg.IconID,
			"version":     cfg.Version,
			"discount":    cfg.Discount,
			"inventory":   cfg.Inventory,
			"buylimittype": cfg.BuyLimitType,
			"buylimitnum":  cfg.BuyLimitNum,
			"proplist":     cfg.PropList,
			"initnum":      cfg.InitNum,
		}
		shoplist = append(shoplist, propdict)
	}

	return map[string]interface{}{
		"shoplist":    shoplist,
		"shopversion": config.ShopVersion,
	}
}

// PresentProp 发放道具
func PresentProp(userid int64, propid, propnum int, now time.Time, store *cache.RedisStore) error {
	strKey := fmt.Sprintf(config.KeyPackage, fmt.Sprintf("%d", userid))
	cfg := config.ShopCfg[propid]
	proplist := cfg.PropList

	propdict := make(map[string]interface{})
	var dbproplist []db.PackageUpdate

	for _, prop := range proplist {
		num, err := store.IncrementHash(strKey, fmt.Sprintf("%d", prop.PID), int64(prop.Num*propnum))
		if err != nil {
			return err
		}
		propdict[fmt.Sprintf("%d", prop.PID)] = num
		dbproplist = append(dbproplist, db.PackageUpdate{
			UserID:    userid,
			PropID:    prop.PID,
			PropNum:   int(num),
			FreshTime: now,
		})
	}

	propdict["freshtime"] = now.Format(time.RFC3339)
	store.SetHash(strKey, propdict)

	// 批量更新数据库
	return db.UpdatePackageInfoBatch(dbproplist)
}

// ShopBuy 购买道具
func ShopBuy(userid, propid, propnum, shopversion, version, paytype int, store *cache.RedisStore) (int, map[string]interface{}) {
	// 检查商城版本
	if shopversion < config.ShopVersion {
		return config.ECShopVersionLow, nil
	}

	// 判断道具是否存在
	cfg, ok := config.ShopCfg[propid]
	if !ok {
		return config.ECShopNotExist, nil
	}

	// 验证客户端版本
	if version < cfg.Version {
		return config.ECShopClientVersionLow, nil
	}

	// 判断支付方式
	validPayType := false
	for _, pt := range cfg.PayType {
		if pt == paytype {
			validPayType = true
			break
		}
	}
	if !validPayType {
		return config.ECShopPaytypeError, nil
	}

	// 计算所需金额
	payAmount, ok := cfg.Pay[paytype]
	if !ok || payAmount < 0 {
		return config.ECShopPaytypeError, nil
	}
	needmoney := int(math.Floor(float64(payAmount) * cfg.Discount * float64(propnum)))

	// 判断余额是否充足
	money := lobby.GetMoney(userid, store)
	if money < needmoney {
		return config.ECShopMoneyNotEnough, nil
	}

	// 扣款
	strKey := fmt.Sprintf(config.KeyPackage, fmt.Sprintf("%d", userid))
	moneyAfter, err := store.IncrementHash(strKey, fmt.Sprintf("%d", config.IDMoney), int64(-needmoney))
	if err != nil {
		return config.ECShopMoneyNotEnough, nil
	}

	if moneyAfter < 0 {
		// 回滚
		store.IncrementHash(strKey, fmt.Sprintf("%d", config.IDMoney), int64(needmoney))
		return config.ECShopMoneyNotEnough, nil
	}

	now := time.Now()
	// 更新数据库
	db.UpdatePackageInfo(int64(userid), config.IDMoney, int(moneyAfter), now)

	// 更新刷新时间
	store.SetHashField(strKey, "freshtime", now.Format(time.RFC3339))

	// 发货
	if err := PresentProp(int64(userid), propid, propnum, now, store); err != nil {
		utils.LogError(err)
		return config.ECShopMoneyNotEnough, nil
	}

	return config.ECReqNormal, map[string]interface{}{
		"money": moneyAfter,
	}
}

